package xj.graph2d.template.uml;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import xj.graph2d.DrawShape;
import xj.graph2d.shapes.uml.ClassShape;
import xj.graph2d.template.UMLTemplate;
import xj.model.uml.Attribute;
import xj.model.uml.Operation;
import xj.model.uml.UMLClass;

public class UMLClassModelListener 
  extends UMLAbstractModelListener {

  public UMLClassModelListener(Map iconMap, UMLTemplate template) {
    this(null, null, iconMap, template);
  }

  public UMLClassModelListener(Object model, 
			       DrawShape shape, 
			       Map iconMap,
			       UMLTemplate template) {
    super(model, shape, iconMap, template);
  }

  @Override
  public void updateModel() {
    if (shape instanceof ClassShape && 
	model instanceof UMLClass) {
      if (debug) { 
	System.out.println("UMLClassModelLisener.updateModel(): shape=" + shape);
      }

      ClassShape clsnode = (ClassShape) shape;
      UMLClass clsmodel = (UMLClass) model;
      String name = clsnode.getClassName();
      clsmodel.setInterface(clsnode.isInterface());
      clsmodel.setAbstract(clsnode.isAbstract());
      clsmodel.setActive(clsnode.isActive());
      clsmodel.setMixin(clsnode.isMixin());
      clsmodel.setException(clsnode.isException());

      String st = clsnode.getClassStereotypes();
      if (name != null) {
	clsmodel.setName(name);
      }
      clsmodel.setStereotypes(st);

      String temp = clsnode.getTemplates();
      clsmodel.setTemplates(temp);

      String pkgname = clsnode.getClassPackage();
      clsmodel.setPackageName(pkgname);

      if (clsnode.isAttrOperCompartmentShown()) {
	clsmodel.removeAllAttributes();
	List<Attribute> attributes = clsnode.getAttributes();
	if (attributes != null) {
	  Iterator<Attribute> iter = attributes.iterator();
	  while (iter.hasNext()) {
	    Attribute attr = iter.next();
	    clsmodel.addAttribute(attr);
	  }
	}

	clsmodel.removeAllOperations();
	List<Operation> operations = clsnode.getOperations();
	if (operations != null) {
	  Iterator<Operation> iter = operations.iterator();
	  while (iter.hasNext()) {
	    Operation oper = iter.next();
	    clsmodel.addOperation(oper);
	  }
	}
      }
    }
  }

  @Override
  public void updateShape() {
    if (shape instanceof ClassShape && 
	model instanceof UMLClass) {
      if (debug) { 
	System.out.println("UMLClassModelLisener.updateShape(): shape=" + shape);
      }

      ClassShape clsnode = (ClassShape) shape;
      UMLClass clsmodel = (UMLClass) model;
      String name = clsmodel.getName();

      boolean isActive = clsmodel.isActive();
      clsnode.setActive(isActive);
      boolean isMixin = clsmodel.isMixin();
      clsnode.setMixin(isMixin);
      boolean isException = clsmodel.isException();
      clsnode.setException(isException);

      boolean isInterface = clsmodel.isInterface();
      boolean isAbstract = clsmodel.isAbstract();
      clsnode.setClassName(name, isInterface, isAbstract);

      String st = clsmodel.getStereotypeString();
      clsnode.setClassStereotypes(st);

      String temp = clsmodel.getTemplates();
      if (temp != null && temp.length() > 0) {
	// did not preserve attr
	DrawShape tshape = clsnode.findTemplateShape();
	if (tshape == null) {
	  tshape = template.makeGenericTemplateShape(60, 20);
	  clsnode.setTemplateShape(tshape);
	}
      }
      clsnode.setTemplates(temp);

      String pkgname = clsmodel.getPackageName();
      clsnode.setClassPackage(pkgname);

      if (clsnode.isAttrOperCompartmentShown()) {
	List<Attribute> attributes = clsmodel.getAttributes();
	clsnode.setAttributes(attributes);
	List<Operation> operations = clsmodel.getOperations();
	clsnode.setOperations(operations);
      }
    }
  }

  protected static final boolean debug = false;

}
